﻿// (c) Copyright 2011 Microsoft Corporation.
// This source is subject to the Microsoft Public License (MS-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
//
// Author: Jason Ginchereau - jasongin@microsoft.com
// Project website: http://reorderlistbox.codeplex.com/
//

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using Microsoft.Phone.Controls;

namespace ReorderListBoxDemo
{
    /// <summary>
    /// Displays a ReorderListBox with demo data and buttons to demo some animated rearrangements.
    /// Also updated to demo a pull-down-to-refresh control.
    /// </summary>
    public partial class MainPage : PhoneApplicationPage
    {
        private static readonly Random random = new Random();

        public MainPage()
        {
            this.InitializeComponent();

            // Create some demonstration data.
            this.DemoData = MainPage.CreateDemoList(30);

            // Set the listbox data context (and the bound ItemsSource) to the demo data collection.
            this.reorderListBox.DataContext = this.DemoData;
        }

        /// <summary>
        /// Gets a demonstration collection of strings. Since this is an ObservableCollection,
        /// changes will be synchronized between this collection and the ReorderListBox that
        /// displays it.
        /// </summary>
        public ObservableCollection<string> DemoData
        {
            get;
            private set;
        }

        #region Demo list generation

        private static ObservableCollection<string> CreateDemoList(int count)
        {
            ObservableCollection<string> list = new ObservableCollection<string>();
            for (int i = 0; i < count; i++)
            {
                string item = MainPage.CreateDemoListItem();
                list.Add(item);
            }
            return list;
        }

        private static string CreateDemoListItem()
        {
            char letter1, letter2, letter3;
            letter1 = (char)('A' + MainPage.random.Next(26));
            do
            {
                letter2 = (char)('A' + MainPage.random.Next(26));
            } while (letter2 == letter1);
            do
            {
                letter3 = (char)('A' + MainPage.random.Next(26));
            } while (letter3 == letter1);

            // Uncomment for testing with list items of different heights.
            ////if (MainPage.random.Next(5) == 0) return "list item " + letter1 + letter2 + letter3 + "\n is two lines";

            return "list item " + letter1 + letter2 + letter3;
        }

        #endregion

        #region Button click handlers

        /// <summary>
        /// Demonstrates animated item addition. Wrapping an insert-item in ReorderListBox.AnimateRearrange
        /// causes the inserted item to fade in while later items slide down to make space.
        /// </summary>
        private void addButton_Click(object sender, EventArgs e)
        {
            TimeSpan animationDuration = TimeSpan.FromSeconds(0.5);

            this.reorderListBox.AnimateRearrange(animationDuration, delegate
            {
                int insertIndex = 0;
                if (this.DemoData.Count > 0)
                {
                    // For demonstration purposes, always insert an item within the visible range.
                    int firstIndex, lastIndex;
                    this.reorderListBox.GetViewIndexRange(false, out firstIndex, out lastIndex);

                    insertIndex = firstIndex + MainPage.random.Next(lastIndex - firstIndex + 1);
                }

                string newItem = MainPage.CreateDemoListItem();
                this.DemoData.Insert(insertIndex, newItem);
            });
        }

        /// <summary>
        /// Demonstrates animated item removal. Wrapping a remove-item in ReorderListBox.AnimateRearrange
        /// causes the removed item to fade out while later items slide up to close the gap.
        /// </summary>
        private void removeButton_Click(object sender, EventArgs e)
        {
            if (this.DemoData.Count > 0)
            {
                TimeSpan animationDuration = TimeSpan.FromSeconds(0.5);

                this.reorderListBox.AnimateRearrange(animationDuration, delegate
                {
                    // For demonstration purposes, always remove an item from within the visible range.
                    int firstIndex, lastIndex;
                    this.reorderListBox.GetViewIndexRange(false, out firstIndex, out lastIndex);

                    int removeIndex = firstIndex + MainPage.random.Next(lastIndex - firstIndex + 1);
                    this.DemoData.RemoveAt(removeIndex);
                });
            }
        }

        /// <summary>
        /// Demonstrates animated item rearranging. Wrapping the sort in ReorderListBox.AnimateRearrange
        /// causes the moved items to slide from their previous location to their new location.
        /// Items which move out of or in to the visible area also fade out / fade in.
        /// </summary>
        private void sortButton_Click(object sender, EventArgs e)
        {
            TimeSpan animationDuration = TimeSpan.FromSeconds(0.75);

            this.reorderListBox.AnimateRearrange(animationDuration, delegate
            {
                List<string> sortList = new List<string>(this.DemoData);
                sortList.Sort();
                this.DemoData.Clear();
                foreach (string item in sortList)
                {
                    this.DemoData.Add(item);
                }
            });
        }

        /// <summary>
        /// Demonstrates animated item rearranging. Wrapping the shuffle in ReorderListBox.AnimateRearrange
        /// causes the moved items to slide from their previous location to their new location.
        /// Items which move out of or in to the visible area also fade out / fade in.
        /// </summary>
        private void shuffleButton_Click(object sender, EventArgs e)
        {
            TimeSpan animationDuration = TimeSpan.FromSeconds(0.75);

            this.reorderListBox.AnimateRearrange(animationDuration, delegate
            {
                List<string> shuffleList = new List<string>(this.DemoData);
                this.DemoData.Clear();
                while (shuffleList.Count > 0)
                {
                    int randomIndex = MainPage.random.Next(shuffleList.Count);
                    string item = shuffleList[randomIndex];
                    shuffleList.RemoveAt(randomIndex);
                    this.DemoData.Add(item);
                }
            });
        }

        #endregion
    }
}